package com.tanqidi.arcgisandroid.ui

import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.Point
import android.os.Bundle
import android.os.Environment
import android.os.SystemClock
import android.text.InputType
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.Toast
import androidx.core.view.GravityCompat
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import com.esri.arcgisruntime.ArcGISRuntimeEnvironment
import com.esri.arcgisruntime.arcgisservices.LabelDefinition
import com.esri.arcgisruntime.arcgisservices.LabelingPlacement
import com.esri.arcgisruntime.data.Feature
import com.esri.arcgisruntime.geometry.*
import com.esri.arcgisruntime.layers.FeatureLayer
import com.esri.arcgisruntime.layers.GroupLayer
import com.esri.arcgisruntime.layers.Layer
import com.esri.arcgisruntime.location.AndroidLocationDataSource
import com.esri.arcgisruntime.mapping.*
import com.esri.arcgisruntime.mapping.labeling.SimpleLabelExpression
import com.esri.arcgisruntime.mapping.view.*
import com.esri.arcgisruntime.symbology.SimpleFillSymbol
import com.esri.arcgisruntime.symbology.SimpleLineSymbol
import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol
import com.esri.arcgisruntime.symbology.TextSymbol
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.Gson
import com.qmuiteam.qmui.util.QMUIDisplayHelper
import com.tanqidi.arcgisandroid.BuildConfig
import com.tanqidi.arcgisandroid.R
import com.tanqidi.arcgisandroid.base.basemap.MapBoxCacheTiledLayer
import com.tanqidi.arcgisandroid.base.basemap.TianDiTuTiledLayer
import com.tanqidi.arcgisandroid.base.utils.*
import com.tanqidi.arcgisandroid.data.layerConfig.Field.Companion.INPUT_TYPE_DOUBLE
import com.tanqidi.arcgisandroid.data.layerConfig.Field.Companion.INPUT_TYPE_INT
import com.tanqidi.arcgisandroid.data.layerConfig.Field.Companion.INPUT_TYPE_STRING
import com.tanqidi.arcgisandroid.data.layerConfig.Field.Companion.SHOW_TYPE_INPUT
import com.tanqidi.arcgisandroid.data.layerConfig.Field.Companion.SHOW_TYPE_SELECT
import com.tanqidi.arcgisandroid.data.layerConfig.Layer.Companion.TYPE_POINT
import com.tanqidi.arcgisandroid.data.layerConfig.Layer.Companion.TYPE_POLYGON
import com.tanqidi.arcgisandroid.data.layerConfig.Layer.Companion.TYPE_POLYLINE
import com.tanqidi.arcgisandroid.data.project.Project
import com.tanqidi.arcgisandroid.databinding.*
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import java.io.File

@AndroidEntryPoint
class HomeFragment : Fragment() {

    private val homeViewModel by viewModels<HomeViewModel>()
    private lateinit var binding: FragmentHomeBinding
    private lateinit var sketchEditor: SketchEditor
    private lateinit var project: Project
    //默认是点
    private var sketchCreationMode = SketchCreationMode.POINT
    //绘制弹窗收集到的内容
    private val dataCollectMap = mutableMapOf<String, Any?>()
    private var updateFeature: Feature? = null
    private val skModeMap = mapOf(
        SketchCreationMode.POINT to TYPE_POINT,
        SketchCreationMode.POLYLINE to TYPE_POLYLINE,
        SketchCreationMode.POLYGON to TYPE_POLYGON
    )
    //当前点击选中的图层
    private lateinit var currentSelectLayer : com.tanqidi.arcgisandroid.data.layerConfig.Layer

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        binding = FragmentHomeBinding.inflate(inflater, container, false)
        homeViewModel.mapView = binding.mapView
        SPUtils.getInstance().getString(getString(R.string.main_project), null)?.let { project = homeViewModel.getProjectByName(it) }
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        initTopAppBar()
        initViewEvent()
        initLiveData()
        setupMap()
    }

    private fun initLiveData() {
        homeViewModel.queryFeatureLiveData.observe(viewLifecycleOwner) {
            this.updateFeature = it
            //重新拿出来图层
            project.layers.filter { layer -> layer.name == it.featureTable.tableName }[0].apply {
                currentSelectLayer = this

                dataCollectMap.clear()
                //从查询出来的要素拿出所有的attribute放到dataCollectMap
                fields.forEachIndexed { index, field ->
                    dataCollectMap[field.field] = it.attributes[field.field]
                }
            }
            //打开绘制菜单
            openDrawDialog(this.updateFeature)
        }
    }

    /**
     * 缩放定位到当前位置
     */
    private fun initLocationDisplay(){
        val locationDisplay = binding.mapView.locationDisplay
        locationDisplay.isShowLocation = true
        locationDisplay.isShowPingAnimation = true
        locationDisplay.isShowAccuracy = true
        locationDisplay.autoPanMode = LocationDisplay.AutoPanMode.RECENTER
        locationDisplay.locationDataSource = AndroidLocationDataSource(requireContext())
        if (!locationDisplay.isStarted) locationDisplay.startAsync()
    }


    @SuppressLint("ClickableViewAccessibility")
    private fun initViewEvent(){
        //点击按钮往屏幕中心放置一个点
        binding.drawPointToMapView.setOnClickListener {
            drawPointToMapView()
        }
        binding.fabDelFeature.setOnClickListener {
            homeViewModel.deleteFeatureByScreenCenterPoint()
        }
        //查询
        binding.fabQuery.setOnClickListener {
            val mapView = binding.mapView
            val center = mapView.visibleArea.extent.center
            val screenCenterPoint = mapView.locationToScreen(center)
            homeViewModel.queryFeatureByScreenCenterPoint(screenCenterPoint)
        }
        //绘制完成
        binding.finish.setOnClickListener {
            /**
             * 在绘制完成之前需要经过一次校验，例如绘制一根线，你最起码需要2个点才能形成线。绘制面最起码需要3个点才能形成面。如果
             * 不加校验直接获取geometry，那么你得到的geometry将很可能是错误的，你拿错误的geometry进行存储这会造成潜在的脏数据
             */
            if(sketchEditor.isSketchValid){
                //通过校验即可得到正确的geometry，后续将会拿它进行各种神奇的操作
                val geometry = sketchEditor.geometry
                //Toast.makeText(requireContext(),xMax+"--"+yMax+" ===> "+Gson().toJson(dataCollectMap),Toast.LENGTH_SHORT).show()
                //临时添加到mapView中显示出来
                //addTempGeometryToMapView(geometry)

                //如果updateFeature 不是 null，就是更新
                if(updateFeature != null){
                    homeViewModel.updateFeature(geometry, currentSelectLayer.name, dataCollectMap, updateFeature!!)
                } else {
                    homeViewModel.addFeature(geometry, currentSelectLayer.name, dataCollectMap)
                }

                sketchEditor.stop()
                //停止绘制，隐藏菜单
                hiddenDrawMenu()
            } else {
                Toast.makeText(requireContext(),"图形格式不正确，请校验",Toast.LENGTH_SHORT).show()
            }
        }
        //停止绘制
        binding.stopDraw.setOnClickListener {
            MaterialAlertDialogBuilder(requireContext())
                .setTitle(resources.getString(R.string.title))
                .setMessage("是否取消绘制图形？")
                .setNeutralButton(resources.getString(R.string.cancel)) { dialog, which -> }
                .setPositiveButton(resources.getString(R.string.ok)) { dialog, which ->
                    sketchEditor.stop()
                    //停止绘制，隐藏菜单
                    hiddenDrawMenu()
                }
                .show()
        }
        //撤回一个点
        binding.undo.setOnClickListener { sketchEditor.undo() }

        //恢复一个点
        binding.redo.setOnClickListener { sketchEditor.redo() }

        //点击绘制按钮，选择将要绘制的类型
        binding.openDrawDialog.setOnClickListener { openDrawDialog() }

        //当前定位
        binding.fabCurrentPosition.setOnClickListener { initLocationDisplay() }

        //mapView各种操作
        val mapView = binding.mapView
        mapView.onTouchListener = object : DefaultMapViewOnTouchListener(requireContext(), mapView) {
            override fun onSingleTapUp(motionEvent: MotionEvent?): Boolean {
                val screenPoint = Point(motionEvent!!.x.toInt(), motionEvent.y.toInt())
                homeViewModel.queryFeatureByScreenCenterPoint(screenPoint)
                return super.onSingleTapUp(motionEvent)
            }
        }
    }

    private fun openDrawDialog(updateFeature: Feature? = null) {
        val dialogBinding = ItemDialogDrawFeatureBinding.inflate(layoutInflater).apply { initDrawDialogView(this, updateFeature) }
        val dialog = MaterialAlertDialogBuilder(requireContext()).setView(dialogBinding.root).show().apply {
            val lp = window?.attributes
            lp?.width = QMUIDisplayHelper.getScreenWidth(requireContext())
            window?.attributes = lp
        }
        dialogBinding.apply {
            cancel.setOnClickListener {
                dialog.dismiss()
                dataCollectMap.clear()
            }
            dismiss.setOnClickListener { dialog.dismiss() }
            accept.setOnClickListener {
                dialog.dismiss()
                //开启绘制
                if(updateFeature != null){
                    sketchEditor.start(updateFeature.geometry)
                } else {
                    sketchEditor.start(sketchCreationMode)
                }
                //显示菜单
                showDrawMenu()
            }
        }
    }


    /**
     * 隐藏绘制菜单
     */
    private fun hiddenDrawMenu(){
        binding.drawMenu.visibility = View.GONE
        binding.openDrawDialog.tag = null
        binding.drawPointToMapView.visibility = View.GONE
    }

    /**
     * 显示绘制菜单
     */
    private fun showDrawMenu() {
        binding.drawMenu.visibility = View.VISIBLE
        binding.openDrawDialog.tag = true
        binding.drawPointToMapView.visibility = View.VISIBLE
    }

    /**
     * 如果不想手动添加，可以模拟点击触摸事件添加一个点到mapView
     */
    private fun drawPointToMapView(){
        binding.mapView.apply {
            val center = visibleArea.extent.center
            val locationToScreen = locationToScreen(center)
            val x = locationToScreen.x.toFloat()
            val y = locationToScreen.y.toFloat()
            dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, x, y, 0))
            dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x, y, 0))
        }
    }

    private fun initTopAppBar() {
        binding.topAppBar.apply {
            title = getSPUtils().getString(getString(R.string.main_project))
            setNavigationOnClickListener {
                binding.drawerLayout.openDrawer(GravityCompat.START)
            }
        }
        binding.navView.setNavigationItemSelectedListener {
            when(it.itemId){
                R.id.nav_test -> {
                    val action = HomeFragmentDirections.actionHomeFragmentToTestFragment()
                    findNavController().navigate(action)
                }
                R.id.nav_project_config -> {
                    val action = HomeFragmentDirections.actionHomeFragmentToProjectConfigFragment()
                    findNavController().navigate(action)
                }
                R.id.nav_env_config -> {
                    findNavController().navigate(HomeFragmentDirections.actionHomeFragmentToEnvConfigFragment())
                }
                R.id.nav_gdb -> {
                    showChoiceDialog(getString(R.string.gdb), getString(R.string.gdbMapJson), getString(R.string.menu_gdb)) {
                        lifecycleScope.launch { homeViewModel.loadGeodatabaseToMapView() }
                    }
                }
                R.id.nav_addkml -> {
                    showChoiceDialog(getString(R.string.kml), getString(R.string.kmlMapJson), getString(R.string.menu_addkml)) {
                        lifecycleScope.launch { homeViewModel.loadKmlToMapView() }
                    }
                }
                R.id.nav_geojson -> {
                    showChoiceDialog(getString(R.string.geojson), getString(R.string.geojsonMapJson), getString(R.string.menu_geojson)) {
                        lifecycleScope.launch { homeViewModel.loadGeoJsonToMapView() }
                    }
                }
                R.id.nav_addshp -> {
                    showChoiceDialog(getString(R.string.shp), getString(R.string.shpMapJson), getString(R.string.menu_addshp)) {
                        lifecycleScope.launch { homeViewModel.loadShpToMapView() }
                    }
                }
                R.id.nav_addtpk -> {
                    showChoiceDialog(getString(R.string.tpk), getString(R.string.tpkMapJson), getString(R.string.menu_addtpk)) {
                        lifecycleScope.launch { homeViewModel.loadTpkToMapView() }
                    }
                }

                R.id.nav_storage -> {
                    val spUtils = getSPUtils()
                    val storageType = spUtils.getString(getString(R.string.storage_type), getString(R.string.storage_geojson))
                    var index = -1
                    val typeList = listOf(getString(R.string.storage_geojson), getString(R.string.storage_shp), getString(R.string.storage_geodatabase)).apply {
                        forEachIndexed { i, item ->
                            if(item == storageType){
                                index = i
                            }
                        }
                    }
                    showSingleChoiceDialog(requireContext(), index, getString(R.string.storage_type), typeList, object : CallBack {
                        override fun callBack(index: Int) {
                            spUtils.put(getString(R.string.storage_type), typeList[index])
                            MaterialAlertDialogBuilder(requireContext())
                                .setTitle("提示")
                                .setCancelable(false)
                                .setMessage("存储模式切换成功")
                                .setPositiveButton("立即重启") { a,b ->
                                    com.blankj.utilcode.util.AppUtils.relaunchApp(true)
                                }
                                .show()
                        }
                    })
                }

                R.id.nav_viewpoint -> {
                    val mapView = binding.mapView
                    val layerMap = linkedMapOf<String, Layer>()
                   mapView.map.operationalLayers.map {
                       if(it is GroupLayer){
                            it.layers.filter { !TextUtils.isEmpty(it.name) }.forEach {
                                layerMap[it.name] = it
                            }
                       }
                   }
                   val singleItems = layerMap.keys.toTypedArray()
                   val checkedItem = -1
                   MaterialAlertDialogBuilder(requireContext())
                        .setTitle(getString(R.string.menu_dingwei))
                        .setPositiveButton(resources.getString(R.string.ok)) { dialog, which -> closeDrawerLayout() }
                        .setSingleChoiceItems(singleItems, checkedItem) { dialog, which ->
                            val layer = layerMap[singleItems[which]]
                            mapView.setViewpointAsync(Viewpoint(layer?.fullExtent), 0.5f)
                        }.show()
                }
            }
            true
        }
    }

    private fun closeDrawerLayout(){
        binding.drawerLayout.close()
    }

    private fun setupMap() {
        //去除许可信息
        //设置apiKey，这是我申请的，你可以去申请一个
        ArcGISRuntimeEnvironment.setApiKey("AAPK1546a8ef92424ed9bd424efb2da6ad29_KM7OcTTXgJPAObA7Boa_PEv3gm6dF8UDMXb9LMmBRFtsCNsyaWomRnBwjIs7KtN")
        val mapView = binding.mapView
        //根据环境配置，设置底图样式
        initBaseMap(mapView)

        //初始化SketchEditor
        sketchEditor = SketchEditor()
        mapView.sketchEditor = sketchEditor
        //去除logo
        mapView.isAttributionTextVisible = false
        //指北针
        val compass = binding.toolkitCompass
        compass.bindTo(mapView)
        //gps定位到当前位置
        initLocationDisplay()

        lifecycleScope.launch {
            //预加载生成groupLayer，让tpk,kml,shp或者featureServer留好位置
            homeViewModel.apply {
                //加载tpk
                loadTpkToMapView()
                //加载kml
                loadKmlToMapView()
                //加载shp
                loadShpToMapView()
                //加载geodatabase
                loadGeodatabaseToMapView()
                //加载geojson
                loadGeoJsonToMapView()

                /**
                 * 加载主项目数据，这个是自己绘制的要素存储的地方入口，在侧边栏可以配置以什么方式来存储数据
                 * 可以是geojson，也可以是shp，也可是是featureServer
                 */
                loadMainProjectToMapView()
//                loadProjectGeoJsonToMapView()
            }
        }
    }



    /**
     * 底图类型
     */
    private fun initBaseMap(mapView: MapView){
        val arcGISMap = ArcGISMap()
        setLoadSettings(arcGISMap)
        val spUtils = getSPUtils()
        when(spUtils.getString(getString(R.string.basemap))){
            //mapbox底图
            getString(R.string.mapbox) -> {
                val createBaseMap = MapBoxCacheTiledLayer.createBaseMap(BuildConfig.mapBoxTile)
                arcGISMap.basemap = createBaseMap
                mapView.map = arcGISMap
            }
            //默认的天地图
            getString(R.string.arcgis) -> {
                val arcGISMap = ArcGISMap(BasemapStyle.ARCGIS_IMAGERY)
                mapView.map = arcGISMap
            }
            //天地图
            getString(R.string.tiandi) -> {
                val webTiledLayer = TianDiTuTiledLayer.CreateTianDiTuTiledLayer(TianDiTuTiledLayer.LayerType.TIANDITU_IMAGE_MERCATOR)
                //标注图层
                val webTiledLayerLable = TianDiTuTiledLayer.CreateTianDiTuTiledLayer(TianDiTuTiledLayer.LayerType.TIANDITU_IMAGE_MERCATOR_LABLE)
                val basemap = Basemap()
                basemap.baseLayers.add(webTiledLayer)
                basemap.baseLayers.add(webTiledLayerLable)
                arcGISMap.basemap = basemap
                mapView.map = arcGISMap
            }
            else -> {
                val createBaseMap = MapBoxCacheTiledLayer.createBaseMap(BuildConfig.mapBoxTile)
                arcGISMap.basemap = createBaseMap
                mapView.map = arcGISMap
            }
        }
    }
    //要素渲染策略，动态渲染DYNAMIC，静态渲染STATIC
    private fun setLoadSettings(arcGISMap: ArcGISMap){
        val loadSettings = LoadSettings()
        loadSettings.preferredPointFeatureRenderingMode = FeatureLayer.RenderingMode.DYNAMIC
        loadSettings.preferredPolylineFeatureRenderingMode = FeatureLayer.RenderingMode.DYNAMIC
        loadSettings.preferredPolygonFeatureRenderingMode = FeatureLayer.RenderingMode.DYNAMIC
        arcGISMap.loadSettings = loadSettings
    }

    /**
     * 复用一下弹窗选择的逻辑，例如 fileFolder是kml，遍历得到所有的文件转成map，key就是文件名value就是文件的绝对路径。
     * 勾选完毕之后就得到了一组 key-value的内容了，然后存进rememberMap转成为json存储在sp中
     * 到第二次打开弹窗的时候判断文件名在不在rememberMap中，就知道是否选中了。
     */
    private fun showChoiceDialog(fileFolder:String,fileTypeJsonKey:String,title:String, okOnClickListener: View.OnClickListener){
        //根据目录来遍历得到所有的文件
        val fileFolder = Environment.getExternalStorageDirectory().absolutePath + File.separator + resources.getString(R.string.app_name) + File.separator + fileFolder
        File(fileFolder).apply {
            if(!exists()) { mkdirs() }
            val fileNamePathMap = listFiles()?.associateBy({it.name},{it.absolutePath})
            val rememberMap = LinkedHashMap<String?,String?>()
            val fileNameList = fileNamePathMap?.keys?.toTypedArray()
            val mapJson = SPUtils.getInstance().getString(fileTypeJsonKey)
            if(!TextUtils.isEmpty(mapJson)){
                val map = Gson().fromJson(mapJson, Map::class.java)
                map.entries.forEach {
                    rememberMap[it.key.toString()] = it.value.toString()
                }
            }
            val checkedItems = if(rememberMap.isEmpty()){
                fileNamePathMap?.map { false }?.toBooleanArray()
            } else {
                fileNamePathMap?.map {
                    rememberMap.containsKey(it.key)
                }?.toBooleanArray()
            }
            MaterialAlertDialogBuilder(requireContext())
                .setTitle(title)
                .setPositiveButton(R.string.ok) { dialog, which ->
                    val mapJson = Gson().toJson(rememberMap)
                    SPUtils.getInstance().put(fileTypeJsonKey, mapJson)
                    closeDrawerLayout()
                    okOnClickListener.onClick(null)
                }
                .setMultiChoiceItems(fileNameList, checkedItems) { dialog, which, checked ->
                    // Respond to item chosen
                    val name = fileNameList?.get(which)
                    if(checked) {
                        rememberMap[name] = fileNamePathMap?.get(name)
                    } else {
                        rememberMap.remove(name)
                    }
                }.show()
        }
    }

    // TODO: 以下是各种组合控件，不是由布局创建的而是由代码动态组合的
    private fun initDrawDialogView(dialogBinding: ItemDialogDrawFeatureBinding, updateFeature: Feature? = null){
        updateFeature?.let {
            when(it.geometry.geometryType){
                GeometryType.POINT -> sketchCreationMode = SketchCreationMode.POINT
                GeometryType.POLYLINE -> sketchCreationMode = SketchCreationMode.POLYLINE
                GeometryType.POLYGON -> sketchCreationMode = SketchCreationMode.POLYGON
                else -> {}
            }
        }

        //创建3个点线面类型按钮组
        dialogBinding.layerTypeGroup.apply {
            listOf(TYPE_POINT, TYPE_POLYLINE, TYPE_POLYGON).forEachIndexed { index, item ->
                ItemToggleGroupItemBinding.inflate(layoutInflater, this, true).apply {
                    materialButton.apply {
                        materialButton.id = index
                        //默认选中点分类
                        isChecked = item == skModeMap[sketchCreationMode]
                        if(isChecked){
                            buildLayerGroup(dialogBinding, item)
                        }
                        text = item
                        setOnClickListener {
                            //点击切换了大分类，这里的dataCollectMap要清空一次，不然会把上一次的内容也存在里面了
                            dataCollectMap.clear()
                            isChecked = true
                            buildLayerGroup(dialogBinding, item)
                            //选择了类型要把该类型转一下给sketchCreationMode，点击确定绘制的时候需要用到该sketchCreationMode
                            when(item){
                                TYPE_POINT -> sketchCreationMode = SketchCreationMode.POINT
                                TYPE_POLYLINE -> sketchCreationMode = SketchCreationMode.POLYLINE
                                TYPE_POLYGON -> sketchCreationMode = SketchCreationMode.POLYGON
                            }
                        }
                        //如果是更新模式，不能切换
                        isEnabled = true
                    }
                }
            }
        }
    }

    /**
     * 创建图层组合
     */
    private fun buildLayerGroup(dialogBinding: ItemDialogDrawFeatureBinding, type: String) {
        //上来就直接清空一下layer_container 和 所有上一次显示出来的field
        dialogBinding.layerContainer.removeAllViews()
        dialogBinding.fieldContainer.removeAllViews()

        //列表当前主项目所有该type类型的layer
        //创建cardView
        UIGenerator.buildCardView(layoutInflater, dialogBinding.layerContainer).apply {
            //创建chipGroup
            ItemChipGroupBinding.inflate(layoutInflater, cardViewContainer, true).apply {
                //创建每一个chip
                project.layers.filter { it.type == type }.forEachIndexed { index, layer ->
                    ItemChipBinding.inflate(layoutInflater, chipGroup, true).apply {
                        chip.apply {
                            text = layer.name

                            //当前图层上次是否选中了
                            if(::currentSelectLayer.isInitialized){
                                isChecked = layer.name == currentSelectLayer.name
                                if(isChecked){
                                    buildField(dialogBinding, layer)
                                }
                            }
                            setOnClickListener {
                                if(isChecked){
                                    currentSelectLayer = layer
                                    //点击了图层chip，创建该layer下面的所有field
                                    buildField(dialogBinding, layer)
                                }

                            }
                        }
                    }
                }

            }
        }

    }

    /**
     * 创建一个字段
     */
    private fun buildField(dialogBinding: ItemDialogDrawFeatureBinding, layer: com.tanqidi.arcgisandroid.data.layerConfig.Layer) {
        //把上一次的所有的field清空掉
        dialogBinding.fieldContainer.removeAllViews()
        //列表该图层里面的所有field并创建控件
        layer.fields.forEachIndexed { index, field ->
            /**
             * 因为字段有两种显示样式，一种是单纯的输入，另外一种是选择
             */
            when(field.showType){
                SHOW_TYPE_INPUT -> {
                    //创建一个cardView包裹住
                    UIGenerator.buildCardView(layoutInflater, dialogBinding.fieldContainer).apply {
                        //创建一个输入框
                        UIGenerator.buildEditInputView(layoutInflater, cardViewContainer).apply {
                            textInputLayout.hint = field.alias
                            //因为是输入，还可以限制输入的类型是什么，int，string，double  ...
                            textInputEditText.apply {
                                when(field.type){
                                    INPUT_TYPE_INT -> inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_VARIATION_NORMAL
                                    INPUT_TYPE_DOUBLE -> inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
                                    INPUT_TYPE_STRING -> inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_NORMAL
                                }
                                setText(dataCollectMap[field.field]?.toString())
                                //输入框如果输入了内容，就把内容放到dataCollectMap中
                                addTextChangedListener {
                                    val inputContent = it.toString().trim()
                                    if(!TextUtils.isEmpty(inputContent)){
                                        dataCollectMap[field.field] = inputContent
                                    } else {
                                        /**
                                         * 上面直接把inputContent放入来理解，这里为什么要放个null呢？这里如果是二次查询编辑呢？你删掉了所有的内容
                                         * 如果不把这个null内容放进去他不会覆盖上一次的内容，可以给个null也或者是个空串也行
                                         */
                                        dataCollectMap[field.field] = null
                                    }
                                }

                            }
                        }
                    }
                }
                SHOW_TYPE_SELECT -> {
                    //创建一个cardView
                    UIGenerator.buildCardView(layoutInflater, dialogBinding.fieldContainer).apply {
                        //创建一个垂直线性布局
                        UIGenerator.buildLinearLayout(layoutInflater, cardViewContainer, myOrientation = LinearLayout.VERTICAL).apply {
                            //创建一个textView
                            UIGenerator.buildTextView(layoutInflater, linearLayoutContainer, myMarginLeft = 16, myMarginTop = 16).apply {
                                textView.text = field.alias
                            }
                            //创建ChipGroup组
                            UIGenerator.buildChipGroupView(layoutInflater, linearLayoutContainer).apply {
                                field.defaultValue.split("\n").forEachIndexed { index, item ->
                                    UIGenerator.buildChipView(layoutInflater, chipGroup).apply {
                                        chip.apply {
                                            text = item
                                            setOnCheckedChangeListener { buttonView, isChecked ->
                                                if(isChecked){
                                                    dataCollectMap[field.field] = item
                                                } else {
                                                    dataCollectMap[field.field] = null
                                                }
                                            }
                                        }

                                    }
                                }

                            }
                        }
                    }

                }
            }

        }

    }




    /**
     * 添加一个临时的geometry图形到mapView中，后续会把geometry持久化成为各种文件，
     * 例如kml，shp，geojson，arcgis server。。。
     *
     * 这里会用到标注，特别实用的功能，很多新人不知道怎么使用它
     */
    private fun addTempGeometryToMapView(geometry: Geometry){
        var labelValue:String? = null
        val geometrySymbol = when(geometry.geometryType){
            GeometryType.POINT -> {
                labelValue = "我是点"
                SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.RED, 12F)
            }
            GeometryType.POLYLINE -> {
                labelValue = "我是线"
                SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.YELLOW, 2F)
            }
            GeometryType.POLYGON -> {
                labelValue = "我是面"
                val lineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLUE, 2F)
                SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.GREEN, lineSymbol)
            }
            else -> null
        }

        val textSymbol = TextSymbol().apply {
            size = 11f
            color = Color.BLUE
            outlineColor = Color.WHITE
            haloColor = Color.WHITE
            haloWidth = 2f
        }
        val labelDefinition = LabelDefinition(SimpleLabelExpression("[label]"), textSymbol).apply {
            isUseCodedValues = true
            placement = LabelingPlacement.AUTOMATIC
        }
        val graphicsOverlay = GraphicsOverlay()
        val attribute = mutableMapOf<String, Any>()
        attribute["label"] = labelValue!!
        val boundary = Graphic(geometry, attribute, geometrySymbol)
        graphicsOverlay.graphics.add(boundary)
        graphicsOverlay.labelDefinitions.add(labelDefinition)
        //开启标注
        graphicsOverlay.isLabelsEnabled = true
        binding.mapView.graphicsOverlays.apply {
            add(graphicsOverlay)
        }
    }

}